<?php

namespace App\Service\authority;
use App\Common\Response\SystemCode;
use App\Model\AuthRole;
use App\Service\authority\AuthRoleService;
use Hyperf\DbConnection\Db;
use Hyperf\Cache\Annotation\Cacheable;
use Hyperf\Cache\Annotation\CachePut;
use App\Service\CommicService;
use Hyperf\Di\Annotation\Inject;
use App\Model\User;
use App\Model\Menu;
use App\Model\Company;
class UserService extends CommicService
{
    #[Inject]
    private AuthRoleService $authRoleService;
    public $expire_in;



    public function search(Array $params){

        $keyword     = $params['keyword'] ?? '';
        $status      = $params['status'] ?? '';
        $roleIds     = $params['role_ids'] ?? 0;
        $pageSize    = $params['pageSize'] ?? 10;
        $page        = $params['page'] ?? 1;

        $query = User::query()->select(['id','username','roles_ids','real_name','email','phone','status','sort','company_id','created_at','updated_at']);


        if ($keyword) {
            $query->orWhere([['username', 'like', '%'.$keyword.'%']])->orWhere([['real_name', 'like', '%'.$keyword.'%']]);
        }
        if ($roleIds) {
            $query->where(['roles_ids' => $roleIds]);
        }
        if ($status != '') {
            $query->where(['status' => $status]);
        }

        $models = $query->orderBy('updated_at','desc')->paginate($pageSize,['*'],'page',$page);
        $items = $models->items();
        $selectData = [];
        foreach ($items as $item){
            $data = $item->toArray();
            if(!empty($item->role)){
                $data['role_name'] = $item->role->name;
            }else{
                $data['role_name'] = '';
            }

            $data['status_name']    =   self::$commonStatus[$item->status];

            $selectData[] =$data;
        }
        $data = $models->toArray();
        $data['data'] = $selectData;
        return $data;
    }

    public function setUser($access_token,$userInfo){

        $redisKey = 'userInfo:'.$access_token;
        $this->redisService->setex($redisKey,14400,json_encode($userInfo));
    }

    public function updateUser($access_token,$userInfo){

        $redisKey = 'userInfo:'.$access_token;
        $this->redisService->setex($redisKey,14400,json_encode($userInfo));
    }

    public function delUser($access_token){

        $this->redisService->del('userInfo:'.$access_token);
    }

    public function getUser($access_token){

      return  $this->redisService->get('userInfo:'.$access_token);
    }

    public function generateToken(string $username)
    {
        $this->access_token = md5($username . time() . rand(1000, 9999));
        $this->expire_in = time()+ 14400;
        return [
            'access_token' => $this->access_token,
            'expire_in'    => $this->expire_in,
        ];
    }
    public function checkUser(string $username,string $password){

       $userInfo =  User::query()->where('username',$username)->select('id','username','company_id','access_token','password','real_name','roles_ids')
           ->where(['status' => User::STATUS_SHOW])
           ->first();
       if(empty($userInfo)){
           return false;
       }
       $password = md5($password);
       if($userInfo->password != $password){
           return false;
       }

       return $userInfo;
    }

    public function getMenus(int $userId = 0, bool $getNew = false){

        $userInfo = User::query()->find($userId);
        if (!$userInfo) {
            return false;
        }

        if ($userInfo->menus && !$getNew) {
            return $userInfo->menus;
        }

        $roleMenus = $userInfo->roles_ids ? $this->authRoleService->roleAuths($userInfo->roles_ids) : [];

        return array_unique(array_filter(array_merge(explode(',', $userInfo['menu_ids']), $roleMenus)));

    }

    public function getMenuData(array $menuIds){

        $menuModel = Menu::query()->where(['status' => Menu::STATUS_SHOW]);

        if (!in_array('all', $menuIds)) {
            $menuModel = $menuModel->andWhere(['id' => $menuIds]);
        }
        return $menuModel->get();
    }

    public function refreshPermissions(string $access_token){

        $userInfo = User::query()->where(['access_token' => $access_token])->select('id','company_id','username','access_token','password','real_name','roles_ids')
            ->where(['status' => User::STATUS_SHOW])->first();
        if(empty($userInfo)){
            return false;
        }
        $tokenInfo = $this->generateToken($userInfo->username);
        if(!empty($userInfo->access_token)){
            $this->delUser($userInfo->access_token);
        }
        $userInfo->access_token = $tokenInfo['access_token'];
        $userInfo->save();
        $menuList = $this->getMenuList($userInfo);
        $appletInfo = $this->getAppletInfo($userInfo,0);
        $oldData = json_decode($this->getUser($userInfo['access_token']),true);
        $returnData   = [
            'token'       => $tokenInfo['access_token'],
            'is_admin'    => $userInfo->role->is_admin,
            'message'     => 'welcome',
            'expire_in'   => $tokenInfo['expire_in'],
            'menuList'    => $menuList['menuList'],
            'permissions' => $menuList['permissions'],
            'user'        => $userInfo,
            'applet'      => $appletInfo,
        ];


        $this->updateUser($userInfo['access_token'],$returnData);
        return $returnData;

    }


    public function createOrUpdate(Array $postData,bool $is_update = false,User $userInfo = null){
        $password = $postData['password'] ?? '';
        $password_repeat = $postData['password_repeat'] ?? '';
        $username = $postData['username'];
        $roles_ids = $postData['roles_ids'];
        $sort = $postData['sort'];
        $real_name = $postData['real_name'];
        $status = $postData['status'];
        $email =  $postData['email'] ?? '';
        $phone = $postData['phone'] ?? '';
        $company_id = $postData['company_id'];
        $is_check_user = true;
        $is_check_password = true;
        $model = !empty($userInfo)? $userInfo : new User();
        //修改
        if($is_update) {
            //修改时判断用户名是否一致
            if ($username == $userInfo->username) {
                $is_check_user = false;
            }
        }
        //检查是否有重名
        if($is_check_user){
            $userInfo = User::query()->where('username',$username)->first();
            if(!empty($userInfo)){
                return $this->response(SystemCode::SYSTEM_ERROR, '用户名已存在');
            }
            $model->username = $username;
        }
        //检查密码是否需要修改
        if($is_update) {
            //修改时判断用户名是否一致
            if (empty($password)) {
                $is_check_password = false;
            }
        }
        if($is_check_password){
            if($password_repeat != $password){
                return $this->response(SystemCode::SYSTEM_ERROR, '密码不一致');
            }
            $model->password = md5($password);
        }
        $roleInfo = AuthRole::query()->where('id',$roles_ids)->first();
        if(empty($roleInfo)){
            return $this->response(SystemCode::SYSTEM_ERROR, '角色不存在');
        }
        $companyInfo = Company::query()->where('id',$company_id)->first();
        if(empty($companyInfo)){
            return $this->response(SystemCode::SYSTEM_ERROR, '公司不存在');
        }

        $model->roles_ids = $roles_ids;
        $model->sort = $sort;
        $model->company_id = $company_id;
        $model->phone = $phone;
        $model->status = $status;
        $model->real_name = $real_name;
        $model->email = $email;
        if($model->save()){
            return $this->response(SystemCode::SYSTEM_SUCCESS);
        }else{
            return $this->response(SystemCode::SYSTEM_ERROR,'保存错误');
        }
    }
}